/**
 * 
 */
package com.sim.server.service;

import com.sim.core.ImChannelContext;
import com.sim.core.ImConst;
import com.sim.core.cache.redis.JedisTemplate;
import com.sim.core.config.ImConfig;
import com.sim.core.message.MessageHelper;
import com.sim.core.packets.*;
import com.sim.core.utils.JsonKit;
import com.sim.core.utils.Md5;
import com.sim.server.config.ImServerConfig;
import com.sim.server.processor.login.LoginCmdProcessor;
import com.sim.server.protocol.AbstractProtocolCmdProcessor;
import com.sim.server.service.impl.UserServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author God
 *
 */
public class LoginServiceProcessor extends AbstractProtocolCmdProcessor implements LoginCmdProcessor {

	private Logger logger = LoggerFactory.getLogger(LoginServiceProcessor.class);

	public static final Map<String, User> tokenMap = new HashMap<String, User>();
	
	/**
	 * 根据用户名和密码获取用户
	 * @param loginReqBody
	 * @param imChannelContext
	 * @return
	 * @author: God
	 */
	@Override
	public User getUser(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
		ImServerConfig imServerConfig = ImConfig.Global.get();
		//开启持久化
		boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
		if(isStore){
			return getUserByToken(imServerConfig,loginReqBody.getToken());
		}
		else{
			return getUser(loginReqBody.getUserId(),loginReqBody.getPassword());
		}
	}

	/**
	 * 根据用户ID和密码获取用户信息（测试用）
	 * @param userId
	 * @param password
	 * @return
	 * @author: God
	 */
	private User getUser(String userId,String password) {
		//demo中用map，生产环境需要用cache
		String text = userId + password;
		String token = Md5.sign(text, ImConst.AUTH_KEY, CHARSET);

		User user = tokenMap.get(token);
		if(user != null){
			return user;
		}
		user = User.newBuilder()
				.userId(userId)
				.nick(userId)
				.avatar(nextImg())
				.status(UserStatusType.ONLINE.getStatus())
				.addGroup(Group.newBuilder().groupId("100").name("S-IM测试群").build())
				.build();

		//缓存用户信息
		if (tokenMap.size() > 10000) {
			tokenMap.clear();
		}
		tokenMap.put(token, user);

		return user;
	}

	/**
	 * 根据token获取用户信息
	 * @param token
	 * @return
	 * @author: God
	 */
	private User getUserByToken(ImServerConfig imServerConfig,String token) {
		//消息持久化助手;
		MessageHelper messageHelper = imServerConfig.getMessageHelper();

		//初始化用户信息
		User user = this.initUserInfo(messageHelper,token).build();

		return user;
	}

	private User.Builder initUserInfo(MessageHelper messageHelper, String token){
		User.Builder builder = User.newBuilder();
		try{
			User user = JedisTemplate.me().get(ImConst.AUTH_KEY + SUFFIX + token,User.class);
			String avatar = StringUtils.isNotBlank(user.getAvatar()) ? user.getAvatar():nextImg();
			builder.userId(user.getUserId())
					.nick(user.getNick())
					.avatar(avatar)
					.status(UserStatusType.ONLINE.getStatus());

			//初始化群组信息
			this.initGroups(messageHelper,user.getUserId(),builder);

			//初始化好友信息
			initFriends(messageHelper,user.getUserId(),builder);
		}
		catch (Exception e){
			logger.error("根据token初始化用户信息失败，token：{}，error：{}", token, e.toString());
		}
		return builder;
	}

	private void initGroups(MessageHelper messageHelper, String userId, User.Builder builder){
		List<String> groups = messageHelper.getGroups(userId);
		try{
			JedisTemplate me = JedisTemplate.me();
			groups.forEach(groupId -> {
				String groupInfoKey = GROUP + SUFFIX + groupId + SUFFIX + INFO;
				String groupInfoStr = me.getString(groupInfoKey);
				Group group = JsonKit.toBean(groupInfoStr,Group.class);
				if(group != null){
					builder.addGroup(group);
				}
			});
		}
		catch (Exception e){
			logger.error("根据userId获取群组信息失败，userId：{}，error：{}", userId, e.toString());
		}
	}

	//todo..................是否需要做，待确认
	private void initFriends(MessageHelper messageHelper, String userId, User.Builder builder){
//		Group myFriend = Group.newBuilder().groupId("1").name("我的好友").build();
//		List<User> myFriendGroupUsers = new ArrayList();
//		User user1 = User.newBuilder()
//					 .userId(UUIDSessionIdGenerator.instance.sessionId(null))
//					 .nick(familyName[RandomUtil.randomInt(0, familyName.length - 1)] + secondName[RandomUtil.randomInt(0, secondName.length - 1)])
//					 .avatar(nextImg())
//					 .build();
//		myFriendGroupUsers.add(user1);
//		myFriend.setUsers(myFriendGroupUsers);
//		builder.addFriend(myFriend);
	}
	
	public String nextImg() {
		return ImgMnService.nextImg();
	}

	/**
	 * 登陆成功返回状态码:ImStatus.C10007
	 * 登录失败返回状态码:ImStatus.C10008
	 * 注意：只要返回非成功状态码(ImStatus.C10007),其他状态码均为失败,此时用户可以自定义返回状态码，定义返回前端失败信息
	 */
	@Override
	public LoginRespBody doLogin(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
		ImServerConfig imServerConfig = ImConfig.Global.get();
		//开启持久化
		boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
		if(isStore){
			UserService userService = new UserServiceImpl();
			if(StringUtils.isNotBlank(loginReqBody.getToken())){
				if (userService.logionByToken(loginReqBody)){
					return LoginRespBody.success();
				}
			}
			else{
				if (userService.logionByPassword(loginReqBody)){
					return LoginRespBody.success();
				}
			}
		}
		else{
			if(StringUtils.isNotBlank(loginReqBody.getUserId()) && StringUtils.isNotBlank(loginReqBody.getPassword())){
				return LoginRespBody.success();
			}
		}

		return LoginRespBody.failed();
	}

	@Override
	public void onSuccess(User user, ImChannelContext channelContext) {
		logger.info("登录成功回调方法");
	}

	@Override
	public void onFailed(ImChannelContext imChannelContext) {
		logger.info("登录失败回调方法");
	}
}
